#ifndef AFFINETRANSFORM_HPP
#define AFFINETRANSFORM_HPP

#include <girlTools/girlToolsImage.hpp>

#include <vector>

#include <boost/foreach.hpp>
#define foreach BOOST_FOREACH


class Transformation
{
public :

    Transformation(const girl::tools::Image &image);
    Transformation();


    /*! Possible Parameters of a Transformation
      * \warning Only Rotations and Translations are used ... .
      */
    struct TransformationParameter
    {

            int angle;
            int dx;
            int dy;
            /*! \brief Creates a Transformation from its own parameters
              *
              */
            Transformation * create(const girl::tools::Image & image);
    };

    /*!
      * \param param = Rotation : angle ou Horizontal = nb pixel horizontal ...
      * \warning ce prototype ne convient pas au transformation affine "combiné"
      */
    girl::tools::Image transformed();
    girl::tools::Image transformed(const girl::tools::Image & image);
    girl::tools::Image transformed(const girl::tools::Image & image, const TransformationParameter &params);

    TransformationParameter getParam()
    {return _params;}

    virtual void setParams(TransformationParameter param)
    {_params = param;}

protected:
    TransformationParameter _params;
    const girl::tools::Image &_image;
};



/*!
  *
  * \brief Static Affine transformations
  *
  * For a more "Object Oriented" approach \see Transformation
  * Example of rotation :
  * \code
  *    girl::tools::Image rotated;
  *    AffineTransform::rotated(input_image, 45, rotated)
  * \endcode
  */
class AffineTransform
{
public:
    AffineTransform();
    static void translated(const girl::tools::Image &image, int dx, int dy, girl::tools::Image &out);

    /*!
      * Returns the out Image as the rotation of image "image" by angle degree. ;-)
      * \param angle en degree
      */
    static void rotated(const girl::tools::Image &image, int angle, girl::tools::Image &out);

    static void clamp(int &x,int &y, const girl::tools::Image &image)
    {

        if(x < 0) x =0;
        if(x > image.width() - 1) x = image.width() -1;
        if(y < 0) y=0;
        if(y > image.height() -1) y = image.height() -1;
    }

    static girl::tools::Image resized(const girl::tools::Image &image, int factor = 2);
};

#endif // AFFINETRANSFORM_HPP
